package com.rambo.hcq.api.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.rambo.hcq.api.service.CommonQueryService;
import com.rambo.hcq.api.wsclient.CommonQueryWs;
import com.rambo.hcq.api.wsclient.CommonQueryWsImplService;
import com.rambo.hcq.api.wsclient.StringArray;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 通用查询服务接口实现类
 *
 * @author Rambo 2017-12-04
 **/
public class CommonQueryServiceImpl implements CommonQueryService {
    private Log logger = LogFactory.get();
    private CommonQueryWs commonQueryWs;

    @Override
    public <T> T getPo(Class<T> t, Map<String, String> andParamMap) {
        try {
            String retStr = recivePo(t, andParamMap, "get");
            return JSONUtil.toBean(retStr, t);
        } catch (Exception e) {
            logger.error("获取单个通用查询业务数据实体表时发生错误:{}", e.toString());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public <T> List<T> listPo(Class<T> t, Map<String, String> andParamMap) {
        try {
            JSONArray poJa = new JSONArray(recivePo(t, andParamMap, "list"));
            logger.info("获取多个通用查询业务数据实体表 json 对象数量:{}", poJa.size());

            poJa.removeIf(next -> ObjectUtil.isNull(next) || "null".equalsIgnoreCase(next.toString()));
            logger.info("进行过滤数据后 json 对象数量:{}", poJa.size());
            return poJa.toList(t);
        } catch (Exception e) {
            logger.error("获取多个通用查询业务数据实体表时发生错误:{}", e.toString());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 调用远程 ws 服务获取通用数据
     *
     * @param t           要获取的实体 po
     * @param andParamMap 参数 map
     * @return 通用数据 json
     */
    private String recivePo(Class t, Map<String, String> andParamMap, String method) throws Exception {
        Assert.notNull(t);
        Assert.notNull(andParamMap);

        String mappingUrl = "http://localhost:4042/hiber-common-query-server/ws/CommonQueryWs?wsdl";
        String po;
        if ("get".equals(method)) {
            po = getService(mappingUrl).getPo(t.getName(), handleParamList(andParamMap));
        } else {
            po = getService(mappingUrl).listPo(t.getName(), handleParamList(andParamMap));
        }

        Assert.notEmpty(po);
        logger.info("调用地址:{},获取表:{}", mappingUrl, t.getName());
        logger.info("返回的对象 json:{}", po);
        return po;
    }

    /**
     * 组织处理调用服务时的参数列表
     *
     * @param andParamMap and语句和参数 Map
     * @return and 语句和参数列表(格式:uuid=?#1045879562314551)
     */
    private StringArray handleParamList(Map<String, String> andParamMap) {
        List<String> allList = new ArrayList<>();
        for (Map.Entry<String, String> andParamMapIn : andParamMap.entrySet()) {
            String andParam = andParamMapIn.getKey() + "#" + andParamMapIn.getValue();
            allList.add(Base64.encode(andParam));
        }

        StringArray stringArray = new StringArray();
        stringArray.setItem(allList);
        return stringArray;
    }

    /**
     * 获取 ws 服务
     *
     * @param mappingUrl 服务地址
     * @return 服务对象
     */
    private CommonQueryWs getService(String mappingUrl) throws MalformedURLException {
        if (this.commonQueryWs == null) {
            this.commonQueryWs = new CommonQueryWsImplService(new URL(mappingUrl)) {
            }.getCommonQueryWsImplPort();
        }
        return this.commonQueryWs;
    }
}